home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / utilities / emulators / apple2emul.lzh / main.c < prev    next >
C/C++ Source or Header  |  1991-04-18  |  4KB  |  251 lines

  1. /*
  2.  *  a2, an Apple II emulator in C
  3.  *  (c) Copyright 1990 by Rich Skrenta
  4.  *
  5.  *  Command line interface written by Tom Markson
  6.  *
  7.  *  Distribution agreement:
  8.  *
  9.  *    You may freely copy or redistribute this software, so long
  10.  *    as there is no profit made from its use, sale, trade or
  11.  *    reproduction.  You may not change this copyright notice,
  12.  *    and it must be included prominently in any copy made.
  13.  *
  14.  *  Send emulator related mail to:  skrenta@blekko.commodore.com
  15.  *                    skrenta@blekko.uucp
  16.  */
  17.  
  18.  
  19.  
  20. #include    <stdio.h>
  21. #include    <signal.h>
  22. #include    <fcntl.h>
  23. #include    "a2.h"
  24.  
  25.  
  26. int save_flags;            /* terminal flags */
  27. char escape_char = '~';
  28.  
  29. unsigned short Pc;
  30. unsigned char Sp = 0xFF;    /* stack pointer     */
  31. unsigned int  A = 0;        /* accumulator        */
  32. unsigned char X = 0;        /* X register        */
  33. unsigned char Y = 0;        /* Y register        */
  34.  
  35. unsigned int N = 0;        /* 7 - sign        */
  36. unsigned int V = 0;        /* 6 - Overflow        */
  37.                 /* 5 - Unused        */
  38. unsigned int B = 1;        /* 4 - Break        */
  39. unsigned int D = 0;        /* 3 - Decimal        */
  40. unsigned int I = 0;        /* 2 - Interrupt    */
  41. unsigned int NZ = 1;        /* 1 - Zero        */
  42. unsigned int C = 0;        /* 0 - Carry        */
  43.  
  44. int term_lines, term_cols;
  45. int running = TRUE;
  46. int tracing = FALSE;
  47.  
  48. int disk[] = {-1, -1};
  49. int write_prot[2];
  50. int drive = 0;
  51.  
  52.  
  53. main(argc, argv)
  54. int argc;
  55. char **argv;
  56. {
  57. int c;
  58. int errflag = 0;
  59. char *f8rom, *d0rom;
  60. int cli_first = FALSE;
  61.  
  62.     safety_check();
  63.     f8rom = "AUTOSTART.ROM";
  64.     d0rom = "APPLESOFT.ROM";
  65.  
  66.     while ((c = getopt(argc, argv, "cim")) != -1) {
  67.         switch (c) {
  68.         case 'c':
  69.             cli_first = TRUE;
  70.             break;
  71.  
  72.         case 'i':
  73.             d0rom = "INTEGER.ROM";
  74.             break;
  75.  
  76.         case 'm':
  77.             f8rom = "MONITOR.ROM";
  78.             break;
  79.  
  80.         case '?':
  81.         default:
  82.             errflag++;
  83.         }
  84.     }
  85.  
  86.     if (errflag) {
  87.         fprintf(stderr, "usage:  %s\n", argv[0]);
  88. fprintf(stderr, "\t-m\tLoad MONITOR.ROM instead of AUTOSTART.ROM at $F800\n");
  89. fprintf(stderr, "\t-i\tLoad INTEGER.ROM instead of APPLESOFT.ROM at $D000\n");
  90. fprintf(stderr, "\t-c\tEnter command mode before executing any instructions\n");
  91.         exit(1);
  92.     }
  93.  
  94.     printf("a2 -- Apple II emulator.  Escape character is %c\n",
  95.                                 escape_char);
  96.  
  97.     if (!bload(f8rom, 0xF800))
  98.         exit(1);
  99.     bload(d0rom, 0xD000);
  100.     bload("DISK.PROM", 0xC600);
  101.  
  102.     if (!InitScreen())
  103.         exit(1);
  104.     ScreenSize(&term_lines, &term_cols);
  105.  
  106.     memory_setup();
  107.     set_special_jumps();
  108.     Pc = join(mem[0xFFFC], mem[0xFFFD]);
  109.  
  110.     if (cli_first)
  111.         cli();
  112.     else
  113.         ClearScreen();
  114.     while (1) {
  115.         set_term();
  116.         run();
  117.         cli();
  118.     }
  119. }
  120.  
  121.  
  122. restore_term() {
  123.  
  124. /*    SetNormal();                /* Turn off inverse video */
  125.     Raw(FALSE);
  126.     fcntl(0, F_SETFL, save_flags);
  127.     signal(SIGINT, SIG_DFL);
  128. }
  129.  
  130.  
  131. set_term() {
  132. int catch_intr();
  133. int cleanup();
  134.  
  135.     signal(SIGINT, catch_intr);
  136.     signal(SIGQUIT, cleanup);
  137.     signal(SIGTERM, cleanup);
  138.     save_flags = fcntl(0, F_GETFL, 0);
  139.     Raw(TRUE);
  140. }
  141.  
  142.  
  143. cleanup() {
  144.  
  145.     restore_term();
  146.     exit(0);
  147. }
  148.  
  149.  
  150. catch_intr() {
  151.  
  152.     signal(SIGINT, catch_intr);
  153.     running = FALSE;
  154.     tracing = FALSE;
  155. }
  156.  
  157.  
  158. bload(fnam, addr)
  159. char *fnam;
  160. unsigned short addr;
  161. {
  162. int fd;
  163. long len;
  164.  
  165.     fd = open(fnam, O_RDONLY);
  166.     if (fd < 0) {
  167.         fprintf(stderr, "can't open %s: ", fnam);
  168.         perror("");
  169.         return(FALSE);
  170.     }
  171.  
  172.     len = 65536 - addr;
  173.  
  174.     if (len == 65536) {        /* stupid $%!*&#~ 16 bit systems */
  175.         if (read(fd, &mem[addr], 4096) < 0) {
  176.             fprintf(stderr, "bad read of %s: ", fnam);
  177.             perror("");
  178.             return(FALSE);
  179.         }
  180.  
  181.         addr += 4096;
  182.         len -= 4096;
  183.     }
  184.  
  185.     if (read(fd, &mem[addr], len) < 0) {
  186.         fprintf(stderr, "bad read of %s: ", fnam);
  187.         perror("");
  188.         return(FALSE);
  189.     }
  190.  
  191.     close(fd);
  192.     return(TRUE);
  193. }
  194.  
  195. bsave(fnam, addr, size)
  196. char *fnam;
  197. unsigned short addr,size;
  198. {
  199.     int fd;
  200.     unsigned sizel;
  201.     int x;
  202.     sizel=size;
  203.     if (sizel==0) sizel=65535;
  204.     fd=open(fnam,O_WRONLY|O_CREAT,0644);
  205.     if (fd < 0) {
  206.         printf("can't open %s: ", fnam);
  207.         perror("");
  208.         return;
  209.     }
  210.     x=write(fd,&mem[addr],sizel);
  211.     if (size == 0)
  212.         x=write(fd,&mem[65535],1);
  213.     if (x==-1) perror("write");
  214.     close(fd);
  215. }
  216.  
  217.  
  218. /*
  219.  *  I make certain assumptions about rollover so that I can do
  220.  *  things like X++ and know that if X is 0xFF it will rollover
  221.  *  to 0x00.  If I didn't know this I'd have to do X = (X+1) & 0xFF
  222.  *  If your machine assert fails on the code below you'll have to
  223.  *  rewrite the code that depends on rollover
  224.  */
  225.  
  226. safety_check() {
  227. unsigned char c;
  228. unsigned short s;
  229.  
  230.     c = 0xFF;
  231.     assert(++c == 0x00);
  232.     assert(--c == 0xFF);
  233.  
  234.     s = 0xFFFF;
  235.     assert(++s == 0x0000);
  236.     assert(--s == 0xFFFF);
  237. }
  238.  
  239.  
  240. asfail(file, line, cond)
  241. char    *file;
  242. int    line;
  243. char    *cond;
  244. {
  245.     fprintf(stderr, "assertion failure: %s (%d): %s\n", file, line, cond);
  246.     restore_term();
  247.     abort();
  248.     exit(1);
  249. }
  250.  
  251.